/*                                  ATELIER                                   */

package edu.gmu.view.canvas.graph;

import java.awt.Dimension;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.awt.image.DataBuffer;
import java.awt.image.DataBufferByte;
import java.awt.image.DataBufferDouble;
import java.awt.image.DataBufferFloat;
import java.awt.image.DataBufferInt;
import java.awt.image.DataBufferShort;
import java.awt.image.DataBufferUShort;
import java.awt.image.WritableRaster;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;

/**
 * This class provides optimized utilities for Image Operations.
 *
 * @author  James H. Pope
 * @version $Revision:$ $Date:$
 */
public final class ImageFactory
{
    /**
     * Clears given BufferedImage.
     *
     * @param BufferedImage to clear.
     */
    public static void clearImage( BufferedImage bufferedImage )
    {
        /*
         * Zero the samples - note this is much better done through
         * the DataBuffer rather than setting the samples through
         * the Raster and much,much better than setting the pixels
         * through the Raster.
         *
         * In order of efficiency ...
         * 
         * dataBuffer.getData()...zeroing
         * writableRaster.setDataElements( j, i, zeroedSample );
         * writableRaster.setDataElements( startX, startY, w, h, rgbArray );
         * writableRaster.setRGB()
         */
        WritableRaster writableRaster = bufferedImage.getRaster();
        DataBuffer dataBuffer = writableRaster.getDataBuffer();
        int dataType = dataBuffer.getDataType();
        /*
         * Cast to appropriate DataBuffer type.
         * Also need to look at getDataBanks - not sure?
         */
        if( dataType == DataBuffer.TYPE_BYTE )
        {
            DataBufferByte byteBuffer = (DataBufferByte)dataBuffer;
            byte[] buffer = byteBuffer.getData();
            for (int i = 0; i < buffer.length; i++)
            {
                buffer[i] = 0;
            }
        }
        else if( dataType == DataBuffer.TYPE_USHORT )
        {
            DataBufferUShort ushortBuffer = (DataBufferUShort)dataBuffer;
            short[] buffer = ushortBuffer.getData();
            for (int i = 0; i < buffer.length; i++)
            {
                buffer[i] = 0;
            }
        }
        else if( dataType == DataBuffer.TYPE_SHORT )
        {
            DataBufferShort shortBuffer = (DataBufferShort)dataBuffer;
            short[] buffer = shortBuffer.getData();
            for (int i = 0; i < buffer.length; i++)
            {
                buffer[i] = 0;
            }
        }
        else if( dataType == DataBuffer.TYPE_INT )
        {
            DataBufferInt intBuffer = (DataBufferInt)dataBuffer;
            int[] buffer = intBuffer.getData();
            for (int i = 0; i < buffer.length; i++)
            {
                buffer[i] = 0;
            }
        }
        else if( dataType == DataBuffer.TYPE_FLOAT )
        {
            DataBufferFloat floatBuffer = (DataBufferFloat)dataBuffer;
            float[] buffer = floatBuffer.getData();
            for (int i = 0; i < buffer.length; i++)
            {
                buffer[i] = 0.0f;
            }
        }
        else if( dataType == DataBuffer.TYPE_DOUBLE )
        {
            DataBufferDouble doubleBuffer = (DataBufferDouble)dataBuffer;
            double[] buffer = doubleBuffer.getData();
            for (int i = 0; i < buffer.length; i++)
            {
                buffer[i] = 0.0;
            }
        }
        else
        {
            /*
             * dataType == DataBuffer.UNDEFINED or otherwise unknown
             */
            String m = "Unknown DataBuffer type \"" + dataType + "\" - cannot clear image";
            throw new IllegalArgumentException( m );
        }
    }
    
    
//    /**
//     * Initializes a graphics with a common set of attributes.  The
//     * normal Swing Components take their default Graphic values from
//     * the LookAndFeel (or commmand line).  This method isn't meant 
//     * to replace this mechanism - this method is meant to provide
//     * a common graphics configuration for custom JComponents that 
//     * do not pick up these defaults from the LookAndFeel.
//     *
//     * @param Graphics graphics to initialize
//     */
//    public static void initGraphics( Graphics2D graphics  )
//    {
//        /*
//         * Turn anti-aliasing on for all layers
//         */
//        graphics.setRenderingHint( RenderingHints.KEY_TEXT_ANTIALIASING,
//                                   RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
//        graphics.setRenderingHint( RenderingHints.KEY_RENDERING,
//                                   RenderingHints.VALUE_RENDER_QUALITY);
//    }

    /**
     * Creates an ImageIcon from the given file name.
     *
     * @param String fielName
     * @return ImageIcon or null if not found or invalid format
     */
    public static ImageIcon makeImageIcon( String fileName )
    {
        try
        {
            URL url = Thread.currentThread().getContextClassLoader().getResource(fileName);

            if( url == null )
            {
                return null;
            }

            ImageIcon imageIcon = new ImageIcon( url );

            return imageIcon;
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * This method looks for the "resource" (i.e. the image file) from
     * the classpath.  I have found it easier to just include a jar
     * of all the images on the classpath.
     */
    public static ImageIcon makeImageIcon(String fileName, int width, int height)
    {
        try
        {
            URL url = Thread.currentThread().getContextClassLoader().getResource(fileName);

            if( url == null )
            {
                return null;
            }

            ImageIcon imageIcon = new ImageIcon( url );

            Image scaledImage = imageIcon.getImage().getScaledInstance( width, height, java.awt.Image.SCALE_SMOOTH );

            return new ImageIcon( scaledImage );
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * This method looks for the "resource" (i.e. the image file) from
     * the classpath.  I have found it easier to just include a jar
     * of all the images on the classpath.
     */
    public static BufferedImage makeBufferedImage(String fileName)
    {
        try
        {
            URL url = Thread.currentThread().getContextClassLoader().getResource(fileName);

            if( url == null )
            {
                return null;
            }

            BufferedImage image = ImageIO.read(url);

            return image;
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        return null;
    }


//    /**
//     * This method returns a buffered image with the contents of an image
//     */
//    public static BufferedImage toBufferedImage(Image image)
//    {
//        if (image instanceof BufferedImage)
//        {
//            return (BufferedImage)image;
//        }
//    }
//        // This code ensures that all the pixels in the image are loaded
//        image = new ImageIcon(image).getImage();
//        // Determine if the image has transparent pixels; for this method's
//        // implementation, see Determining If an Image Has Transparent Pixels
//        boolean hasAlpha = hasAlpha(image);
//        // Create a buffered image with a format that's compatible with the screen
//        BufferedImage bimage = null;
//        GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
//        try
//        {
//            // Determine the type of transparency of the new buffered image
//            int transparency = Transparency.OPAQUE;
//            if (hasAlpha)
//            {
//                transparency = Transparency.BITMASK;
//            }
//        }
//        // Create the buffered image
//        GraphicsDevice gs = ge.getDefaultScreenDevice();
//        GraphicsConfiguration gc = gs.getDefaultConfiguration();
//        bimage = gc.createCompatibleImage( image.getWidth(null), image.getHeight(null), transparency);
//        }
//        catch (HeadlessException e)
//        {
//            // The system does not have a screen
//        }
//
//        if (bimage == null)
//        {
//            // Create a buffered image using the default color model
//            int type = BufferedImage.TYPE_INT_RGB;
//            if (hasAlpha)
//            {
//                type = BufferedImage.TYPE_INT_ARGB;
//            }
//            bimage = new BufferedImage(image.getWidth(null), image.getHeight(null), type);
//        }
//        // Copy image to buffered image
//        Graphics g = bimage.createGraphics();
//        // Paint the image onto the buffered image
//        g.drawImage(image, 0, 0, null);
//        g.dispose();
//        return bimage;
//    }


    
}

/*                                  ATELIER                                   */